package com.codeoss.framework.data.parser;

import java.util.ArrayList;
import java.util.List;

import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;

import com.codeoss.framework.data.metadata.Column;
import com.codeoss.framework.data.metadata.ColumnValidationRule;
import com.codeoss.framework.expression.Expression;
import com.codeoss.framework.expression.ExpressionUtil;
import com.codeoss.framework.util.DictDef;
import com.codeoss.framework.util.LookupInfo;
import com.codeoss.framework.util.StringUtils;
import com.codeoss.framework.util.Utils;
import com.codeoss.framework.view.datasource.DataSourceConfig;
import com.fasterxml.jackson.databind.JsonNode;
import com.fasterxml.jackson.databind.node.ArrayNode;
import com.fasterxml.jackson.databind.node.ObjectNode;

@Component("dataColumnParser")
public class ColumnParser implements IColumnParser {
	@Autowired
	private Utils utils;
	@Override
	public Column parser(IDataParseContext dataParseContext, ObjectNode objectNode) {
		// TODO Auto-generated method stub
		Column column = new Column();

		JsonNode jsonNode = objectNode.get("name");
		if (jsonNode != null) {
			column.setName(jsonNode.asText());
		}

		jsonNode = objectNode.get("columnName");
		if (jsonNode != null) {
			column.setColumnName(jsonNode.asText());
		}

		jsonNode = objectNode.get("dataType");
		if (jsonNode != null && !"null".equals(jsonNode.asText())) {
			column.setDataType(jsonNode.asText());
		}

		jsonNode = objectNode.get("notNull");
		if (jsonNode != null) {
			column.setNullable(!jsonNode.asBoolean());
		}

		jsonNode = objectNode.get("length");
		if (jsonNode != null) {
			column.setLength(jsonNode.asInt());
		}

		jsonNode = objectNode.get("precision");
		if (jsonNode != null) {
			column.setPrecision(jsonNode.asInt());
		}

		jsonNode = objectNode.get("primaryKey");
		if (jsonNode != null) {
			column.setPrimaryKey(jsonNode.asBoolean());
		}

		column.setTable(dataParseContext.getTable());

		jsonNode = objectNode.get("defaultValueExpression");
		if (jsonNode != null && !"null".equals(jsonNode.asText())) {
			String defaultValueExpression = jsonNode.asText();
			if (!StringUtils.isEmpty(defaultValueExpression) && !"null".equals(jsonNode.asText())) {
				column.setDefaultValueExpression(defaultValueExpression);
			}
		}

		jsonNode = objectNode.get("requiredExpression");
		if (jsonNode != null && !"null".equals(jsonNode.asText())) {
			String requiredExpression = jsonNode.asText();
			if (!StringUtils.isEmpty(requiredExpression) && !"null".equals(jsonNode.asText())) {
				column.setRequiredExpression(requiredExpression);
			}
		}

		jsonNode = objectNode.get("readOnlyExpression");
		if (jsonNode != null && !"null".equals(jsonNode.asText())) {
			String readOnlyExpression = jsonNode.asText();
			if (!StringUtils.isEmpty(readOnlyExpression) && !"null".equals(jsonNode.asText())) {
				column.setReadOnlyExpression(readOnlyExpression);
			}
		}

		jsonNode = objectNode.get("property");
		if (jsonNode != null) {
			String property = jsonNode.asText();
			if (StringUtils.isEmpty(property)) {
				property = utils.getPropertyName(column.getColumnName());
			}
			column.setProperty(property);
		} else {
			String property = utils.getPropertyName(column.getColumnName());
			column.setProperty(property);
		}

		jsonNode = objectNode.get("sqlType");
		if (jsonNode != null && !"null".equals(jsonNode.asText())) {
			column.setSqlType(jsonNode.asText());
		}

		jsonNode = objectNode.get("unique");
		if (jsonNode != null) {
			column.setUnique(jsonNode.asBoolean());
		}

		jsonNode = objectNode.get("parentColumn");
		if (jsonNode != null) {
			column.setParentColumn(jsonNode.asBoolean());
		}

		jsonNode = objectNode.get("codeColumn");
		if (jsonNode != null) {
			column.setCodeColumn(jsonNode.asBoolean());
		}
		
		jsonNode = objectNode.get("nameColumn");
		if (jsonNode != null) {
			column.setNameColumn(jsonNode.asBoolean());
		}
		
		jsonNode = objectNode.get("exportColumn");
		if (jsonNode != null) {
			column.setExportColumn(jsonNode.asBoolean());
		}
		
		jsonNode = objectNode.get("storeColumn");
		if (jsonNode != null) {
			column.setStoreColumn(jsonNode.asBoolean());
		}
		
		jsonNode = objectNode.get("allowLogging");
		if (jsonNode != null) {
			column.setAllowLogging(jsonNode.asBoolean());
		}
		
		LookupInfo lookupInfo = null;

		jsonNode = objectNode.get("dict");
		if (jsonNode != null) {
			String dict = jsonNode.asText();
			if (!StringUtils.isEmpty(dict) && !"null".equals(jsonNode.asText())) {
				DictDef dictDef = new DictDef();
				dictDef.setRefCode(dict);
				lookupInfo = new LookupInfo();
				lookupInfo.setDictDef(dictDef);
				lookupInfo.setValueColumn("value");
				lookupInfo.setDisplayColumn("name");
			}
		}

		jsonNode = objectNode.get("refTable");
		if (jsonNode != null) {
			String refTable = jsonNode.asText();
			if (!StringUtils.isEmpty(refTable) && !"null".equals(jsonNode.asText())) {
				lookupInfo = new LookupInfo();
				String valueColumn = objectNode.get("valueColumn").asText();
				String displayColumn = objectNode.get("displayColumn").asText();
				lookupInfo.setValueColumn(valueColumn);
				lookupInfo.setDisplayColumn(displayColumn);
				DataSourceConfig dataSourceConfig = new DataSourceConfig();
				lookupInfo.setDataSourceConfig(dataSourceConfig);
				dataSourceConfig.setTableName(refTable);
				if (objectNode.get("whereClause") != null) {
					String whereClause = objectNode.get("whereClause").asText();
					if (!"null".equals(whereClause)) {
						Expression expression = new Expression();
						expression.setScriptType(Expression.EXPRESSION_TYPE_JAVASCRIPT);
						expression.setScript(whereClause);
						dataSourceConfig.setWhereClause(expression);
					}
				}
				if (objectNode.get("dynamicWhereClause") != null) {
					String dynamicwhereclause = objectNode.get("dynamicWhereClause").asText();
					if (!StringUtils.isEmpty(dynamicwhereclause) && !"null".equals(dynamicwhereclause)) {
						dataSourceConfig.setDynamicWhereClause(dynamicwhereclause);
					}
				}
			}
		}
		column.setLookupInfo(lookupInfo);

		jsonNode = objectNode.get("validationRuleList");
		if (jsonNode != null) {
			ArrayNode arrayNode = (ArrayNode) jsonNode;
			List<ColumnValidationRule> columnValidationRuleList=new ArrayList<ColumnValidationRule>();
			column.setColumnValidationRuleList(columnValidationRuleList);
			for (int i = 0; i < arrayNode.size(); i++) {
				ObjectNode node = (ObjectNode) arrayNode.get(i);
				ColumnValidationRule columnValidationRule = new ColumnValidationRule();
				columnValidationRuleList.add(columnValidationRule);
				
				String validationRuleName = node.get("validationRuleName").asText();
				columnValidationRule.setValidationRuleName(validationRuleName);

				String validationRule = node.get("validationRule").asText();
				Expression expression = ExpressionUtil.convertToExpression(validationRule,
						Expression.EXPRESSION_TYPE_JAVASCRIPT);
				columnValidationRule.setValidationRuleExpression(expression);

				String validationErrorMessage = node.get("validationErrorMessage").asText();
				columnValidationRule.setValidationErrorMessage(validationErrorMessage);
			}
		}
		return column;
	}

}
